package demo.fileserver;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Dict;
import cn.hutool.extra.servlet.ServletUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

/**
 * 文件处理后台
 * @author zhangyuxi
 * @date 2025/6/18 17:04
 */
@Slf4j
@RestController
@RequestMapping("/api")
public class FileController {
    @Value("${fileserver.root}")
    private String rootDir;

    @RequestMapping("/hello")
    public String hello() {
        return "hello world from server!";
    }

    @RequestMapping("/fileList")
    public Object fileList(@RequestParam(value = "base", required = false) String base) {
        List<Dict> result = new ArrayList<>();
        Assert.isTrue(base.startsWith("/"));
        base = rootDir+base;
        File baseFile = new File(base);
        File[] files = baseFile.listFiles();
        if(files==null || files.length==0) {
            log.info("目录{}是空的", base);
            return result;
        }
        for(File f: files) {
            Dict dict = new Dict();
            dict.put("type",f.isFile()?"文件" : "目录");
            dict.put("name",f.getName());
            dict.put("size",FileUtil.readableFileSize(f));
            result.add(dict);
        }
        // 最后,进行排序,目录往前排,目录一样的,按名字排列
        result.sort((a,b)->{
            if(a.getStr("type").equals("目录") && b.getStr("type").equals("文件")) {
                return -1;
            }
            if(a.getStr("type").equals("文件") && b.getStr("type").equals("目录")) {
                return 1;
            }
            return a.getStr("name").compareTo(b.getStr("name"));
        });
        return result;
    }

    @RequestMapping("/download")
    public void download(@RequestParam("filePath")String filePath, HttpServletResponse response) throws IOException {
        log.info("文件下载:{}", filePath);
        Assert.isTrue(filePath.startsWith("/"));
        filePath = rootDir + filePath;
        File f = new File(filePath);
//        ServletUtil.write(response, f); // 暂时不用这种方式
        String encodedFileName = URLEncoder.encode(f.getName(), "UTF-8");
        response.setHeader("Content-Disposition",
                "attachment; filename=\"" + encodedFileName + "\"");
        FileInputStream fileInputStream = new FileInputStream(f);
        StreamUtils.copy(fileInputStream, response.getOutputStream());
        fileInputStream.close();
        return;
    }

    @RequestMapping("/download/{filePath}")
    public void download2(@PathVariable("filePath")String filePath, HttpServletResponse response) throws IOException {
        log.info("文件下载:{}", filePath);
//        Assert.isTrue(filePath.startsWith("/"));
        filePath = "/"+filePath;
        filePath = rootDir + filePath;
        File f = new File(filePath);
//        ServletUtil.write(response, f); // 暂时不用这种方式
        String encodedFileName = URLEncoder.encode(f.getName(), "UTF-8");
        response.setHeader("Content-Disposition",
                "attachment; filename=\"" + encodedFileName + "\"");
        StreamUtils.copy(new FileInputStream(f), response.getOutputStream());
        return;
    }

    @RequestMapping("/upload")
    public void upload(@RequestParam("file") MultipartFile[] files, @RequestParam("currentPath") String currentPath) throws IOException {
        currentPath = rootDir+currentPath;
        for(MultipartFile f: files) {
            String name = f.getOriginalFilename();
            FileUtil.writeBytes(f.getBytes(), new File(currentPath, name));
        }
    }

    @DeleteMapping("/delete")
    public void delete(@RequestParam("filePath")String filePath) {
        log.info("文件删除:{}", filePath);
        Assert.isTrue(filePath.startsWith("/"));
        filePath = rootDir + filePath;
        File f = new File(filePath);
        FileUtil.del(f);
        return;
    }

    @GetMapping("/createFolder")
    public String createFolder(@RequestParam("folderName")String folderName) {
        if(!folderName.startsWith("/")) {
            folderName = "/" + folderName;
        }
        folderName = rootDir + folderName;
        log.info("创建目录:{}", folderName);
        FileUtil.mkdir(folderName);
        return "success";
    }
}
